﻿namespace MicroCloud.Message.Events
{
    /// <summary>
    /// 集线器建立新连接事件处理器
    /// </summary>
    public class HubConnectionEventHandler : EventHandlerBase<HubConnectionEventData>
    {
        #region "属性"
        #region "获取 服务提供者"
        /// <summary>
        /// 获取 服务提供者
        /// </summary>
        protected IServiceProvider ServiceProvider { get; }
        #endregion
        #region "获取 日志记录器"
        /// <summary>
        /// 获取 日志记录器
        /// </summary>
        protected ILogger Logger => ServiceProvider.GetLogger(GetType());
        #endregion
        #region "获取 当前用户的基本功能"
        /// <summary>
        /// 获取 当前用户的基本功能
        /// </summary>
        protected IPrincipal Principal => ServiceProvider.GetService<IPrincipal>();
        #endregion
        #region "获取 SignalR服务"
        /// <summary>
        /// 获取 SignalR服务
        /// </summary>
        protected ISignalRService SignalRService => ServiceProvider.GetService<ISignalRService>();
        #endregion
        #region "获取 消息服务"
        /// <summary>
        /// 获取 消息服务
        /// </summary>
        protected IMessageService MessageService => ServiceProvider.GetService<IMessageService>();
        #endregion

        #endregion

        #region "构造函数"
        #region "初始化一个集线器建立新连接事件处理器的新实例"
        /// <summary>
        /// 初始化一个集线器建立新连接事件处理器 <see cref="HubConnectionEventHandler"/> 的新实例
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public HubConnectionEventHandler(IServiceProvider provider)
        {
            ServiceProvider = provider;
        }
        #endregion

        #endregion

        #region "方法"
        #region "事件处理"
        /// <summary>
        /// 事件处理
        /// </summary>
        /// <param name="eventData">事件源数据</param>
        /// <param name="provider">服务提供者</param>
        public override void Handle(HubConnectionEventData eventData, IServiceProvider provider)
        {
            var groupKeys = new List<string>();
            //获取已连接用户的组织架构，并自动加入组
            var currentOrganizationId = Principal.Identity.GetCurrentOrganizationId();
            var currentDepartmentId = Principal.Identity.GetCurrentDepartmentId();
            var organizationId = currentDepartmentId.IsMissing() ? currentOrganizationId : currentDepartmentId;
            if (!organizationId.IsMissing())
            {
                groupKeys.AddIfNotExist(MessageService.GetGroupKeyByOrganization(currentOrganizationId));

                var organizationProvider = ServiceProvider.GetService<IOrganizationProvider>();
                var childKeys = organizationProvider?.GetChildOrganizations(organizationId).Select(o => MessageService.GetGroupKeyByOrganization(o.Id)).ToList();
                var parentKeys = organizationProvider?.GetParentOrganizations(organizationId).Select(o => MessageService.GetGroupKeyByOrganization(o.Id)).ToList();
                if (childKeys != null)
                {
                    groupKeys = groupKeys.Union(childKeys).ToList();
                }
                if (parentKeys != null)
                {
                    groupKeys = groupKeys.Union(parentKeys).ToList();
                }
            }
            //获取已连接用户的角色，并自动加入组
            var onlineRoles = Principal.Identity.GetRoles();
            if (onlineRoles?.Length > 0)
            {
                foreach (var onlineRole in onlineRoles)
                {
                    groupKeys.AddIfNotExist(MessageService.GetGroupKeyByRole(onlineRole.Id));
                }
            }

            //加入组
            SignalRService.AddToGroup(eventData.CallerContext.ConnectionId, groupKeys.ToArray()).Wait();
        }
        #endregion

        #endregion

    }

    /// <summary>
    /// 集线器终止连接事件处理器
    /// </summary>
    public class HubDisconnectionEventHandler : EventHandlerBase<HubDisconnectionEventData>
    {
        #region "属性"
        #region "获取 服务提供者"
        /// <summary>
        /// 获取 服务提供者
        /// </summary>
        protected IServiceProvider ServiceProvider { get; }
        #endregion
        #region "获取 日志记录器"
        /// <summary>
        /// 获取 日志记录器
        /// </summary>
        protected ILogger Logger => ServiceProvider.GetLogger(GetType());
        #endregion
        #region "获取 当前用户的基本功能"
        /// <summary>
        /// 获取 当前用户的基本功能
        /// </summary>
        protected IPrincipal Principal => ServiceProvider.GetService<IPrincipal>();
        #endregion
        #region "获取 SignalR服务"
        /// <summary>
        /// 获取 SignalR服务
        /// </summary>
        protected ISignalRService SignalRService => ServiceProvider.GetService<ISignalRService>();
        #endregion

        #endregion

        #region "构造函数"
        #region "初始化一个集线器终止连接事件处理器的新实例"
        /// <summary>
        /// 初始化一个集线器终止连接事件处理器 <see cref="HubDisconnectionEventHandler"/> 的新实例
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public HubDisconnectionEventHandler(IServiceProvider provider)
        {
            ServiceProvider = provider;
        }
        #endregion

        #endregion

        #region "方法"
        #region "事件处理"
        /// <summary>
        /// 事件处理
        /// </summary>
        /// <param name="eventData">事件源数据</param>
        /// <param name="provider">服务提供者</param>
        public override void Handle(HubDisconnectionEventData eventData, IServiceProvider provider)
        {
            //获取已连接组键值集合，并自动离开组
            var connectedGroupKeys = SignalRService.UserCache.GetUserGroupByConnection(eventData.CallerContext.ConnectionId).Select(o => o.GroupKey).Distinct().ToList();
            //离开组
            SignalRService.RemoveFromGroup(eventData.CallerContext.ConnectionId, connectedGroupKeys.ToArray()).Wait();
        }
        #endregion

        #endregion

    }

}
